<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <script>
      // Reflect  反射机制
      // Reflect 为了操作对象 提供了api
      var obj = {
        name: '李四',
        age: 2,
        aihao: ['吃', '睡', '玩'],
        tizhong: 120
      }
      Object.defineProperty(obj, 'sex', {
        value: '男',
        writable: false,
        enumerable: false,
        configurable: false
      })
      console.log(obj)
      // 1  Reflect.defineProperty 修改和添加对象的属性
      Reflect.defineProperty(obj, 'shengao', {
        value: '180',
        writable: false,
        enumerable: false,
        configurable: false
      })
      console.log(obj)
      //2.Reflect.apply(target, thisArgument, argumentsList)
      var name = '张三'
      function say(tips) {
        console.log(tips + '---' + this.name)
      }
      // say.apply(obj, [188])
      Reflect.apply(say, obj, [188])
      //    3.Reflect.construct()
      // Reflect.construct(target, argumentsList[, newTarget]) 方法的行为有点像 new 操作符 构造函数
      // var date = new Date('2020-08-08')
      var date = Reflect.construct(Date, ['2020-08-08'])
      console.log(date)
      // 4.Reflect.delete​Property()
      // Reflect.deleteProperty 允许你删除一个对象上的属性。返回一个 Boolean 值表示该属性是否被成功删除。
      // 它几乎与非严格的 delete operator 相同。
      // 语法
      var flag = Reflect.deleteProperty(obj, 'aihao')
      console.log(flag)
      console.log(obj)
      // 5.Reflect.get()
      // Reflect.get() 方法的工作方式，就像从 object (target[propertyKey]) 中获取属性，但它是作为一个函数执行的。
      // Reflect.get(target, propertyKey[, receiver])
      var tizhong = Reflect.get(obj, 'tizhong')
      console.log(tizhong)
      //
      // 6.Reflect.get​OwnProperty​Descriptor()

      // 静态方法 Reflect.getOwnPropertyDescriptor() 与 Object.getOwnPropertyDescriptor() 方法相似。
      // 如果在对象中存在，则返回给定的属性的属性描述符，否则返回undefined。
      var pot = Reflect.getOwnPropertyDescriptor(obj, 'shengao')
      console.log(pot)
      //7.Reflect.getPrototypeOf()
      // 静态方法 Reflect.getPrototypeOf() 与 Object.getPrototypeOf() 方法是一样的。
      // 都是返回指定对象的原型（即，内部的 [[Prototype]] 属性的值）。
      class Cat {
        say() {}
      }
      var ketimao = new Cat()
      var prop = Reflect.getPrototypeOf(ketimao)
      console.log(prop)
      //
      // 8.Reflect.has()
      // Reflect.has 用于检查一个对象是否拥有某个属性， 相当于in 操作符
      var fg = Reflect.has(obj, 'age')
      console.log(fg)
      //    9.Reflect.isExtensible()
      // Reflect.isExtensible 判断一个对象是否可扩展 （即是否能够添加新的属性），
      // 它与 Object.isExtensible() 方法一样。
      var fa = Reflect.isExtensible(obj)
      console.log(fa)
      //
      // 10.Reflect.own​Keys()

      // Reflect.ownKeys 方法返回一个由目标对象自身的属性键组成的数组。它的返回值等同于
      console.log(Object.keys(obj)) //["name", "age", "tizhong"]
      console.log(Reflect.ownKeys(obj)) //["name", "age", "tizhong", "sex", "shengao"]
      //
      // 11.Reflect.prevent​Extensions()
      // Reflect.preventExtensions 方法阻止新属性添加到对象
      // 例如：防止将来对对象的扩展被添加到对象中)。该方法与 Object.preventExtensions() 方法一致
      // Reflect.preventExtensions(obj)
      obj.kuaile = '快乐'
      console.log(obj)
      // 12.Reflect.set()
      // Reflect.set 方法允许你在对象上设置属性。
      // 它的作用是给属性赋值并且就像 property accessor 语法一样，但是它是以函数的方式。
      Reflect.set(obj, 'tianqi', '晴朗')
      console.log(obj)
      //
    </script>
  </body>
</html>
